/*
* Copyright (c) 2013 City University of Hongkong.
*                    Cloud computing security group.
* 
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation the rights to use, copy, modify, merge, publish,
* distribute, sublicense, and/or sell copies of the Software, and to
* permit persons to whom the Software is furnished to do so, subject to
* the following conditions:
* 
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
* 
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/

/*
* graph_partition.h - graph partition methodology implementation.
*
* Authors: Xingliang Yuan     
* Emails:  xyuan86@gmail.com
*
*/

#ifndef GRAPH_PARTITION_H
#define GRAPH_PARTITION_H
#include "../graph/ff_graph.h"
#include "../algorithm/mc_utility.h"

#if !defined(__cdecl)
#define __cdecl
#endif

#ifdef __cplusplus
extern "C" {
#endif

    void __cdecl
        HMETIS_PartRecursive(int ncells, int nnets, int *cellwgt, int *netptr,
        int *netind, int *netwgt, int nparts, int ufactor, int *options,
        int *part, int *edgecut);

    void __cdecl
        HMETIS_PartKway(int ncells, int nnets, int *cellwgt, int *netptr,
        int *netind, int *netwgt, int nparts, int ufactor, int *options,
        int *part, int *edgecut);

#ifdef __cplusplus
}
#endif

class graph_partition: public mc_utility
{
protected:

    vector <unsigned int> mapping; //store non-black vertex relabel info

    vector <unsigned int> gray_set; //store gray vertex set

    vector <unsigned int> white_adjv_set; //store white adj v to gray vertexes

    //set <set<unsigned int>> gray_reach_list; 
    vector <vector<unsigned int>> gray_reach_list; 

    /* 
     * gray vertex to gray ones full reachable list; 
     */
    vector <vector<unsigned int>> full_reach_list; 

    vector <edge> temp_edge_set; // for refinement

    unsigned int prime_path_num;

    unsigned int black_num; //black vertex number

    unsigned int color_num; //color vertex number

    vector <edge> non_black_edges; // relabeled non-black vertex edges

    /*  
    * description: graph partition refinement to group close 
    * param: ff_graph instance 
    * return: 
    */
    void partition_refinement(class ff_graph& ff_obj);

     /*  
    * description: graph partition refinement to group close 
    * param: ff_graph instance 
    * return: 
    */
    void gen_gray_reach_list(class ff_graph& ff_obj);

    /*  
    * description: hiding vertex adjacent edges and relabeling
    * param: ff_graph instance; parition_file hgr.part.Npart
    * return: 
    */
    void subgraph_extraction(class ff_graph& ff_obj, char* partition_file);

    /*  
    * description: record black vertex topology at local _black_p2.dag
    * param: 
    * return: 
    */
    void write_black_graph(class ff_graph& ff_obj, char* benchmark); 

    /*  
    * description: record mapping due to relabel
    * param: 
    * return: 
    */
    void write_mapping(class ff_graph& ff_obj, char* benchmark); 

    /*  
    * description: create partition graph file _p2.dag to cloud
    * param: 
    * return: 
    */
    void write_partition_graph(class ff_graph& ff_obj, char* benchmark); 

    /*  
    * description: create delay file p1.delay p2.delay p3.delay 
    * param: 
    * return: 
    */
    void write_delay(class ff_graph& ff_obj, char* benchmark); 

public: 
    /*  
    * description: three phase graph partition techniques
    * param: ff_graph instance; phase: 1=phase one, 2=phase two, 3=phase three;
    *        percent critical vertex
    * return: 
    */
    void ip_protection(class ff_graph& ff_obj, char* benchmark);

    /*  
    * description: generate hgr file for shmetis input from dag file
    * param: ff_graph instance; phase: 1=phase one, 2=phase two, 3=phase three;
    *        percent critical vertex
    * return: 
    */
    void dag_to_hgr(class ff_graph& ff_obj, char* hgr_file);

    /*  
    * description: generate fix file, black and gray assigned to same partition
    * param: ff_graph instance; fix file
    * return: 
    */
    void partition_to_fix(class ff_graph& ff_obj, 
                    char* hgr_file, char* fix_file);

};

#endif // GRAPH_PARTITION_H
